package com.gaswell.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.builder.ExcelReaderSheetBuilder;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gaswell.aop.annotation.JHPermission;
import com.gaswell.common.log.LogAnnotation;
import com.gaswell.config.listener.RtuDataListener;
import com.gaswell.entity.Qba01;
import com.gaswell.mapper.RtuDataMapper;
import com.gaswell.pojo.RtuData;
import com.gaswell.service.*;
import com.gaswell.utils.DateUtils;
import com.gaswell.utils.JwtUtils;
import com.gaswell.vo.FindLastDataVo2;
import com.gaswell.vo.QjVo;
import com.gaswell.vo.Result;
import com.gaswell.vo.RtuDataVo;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@Api(tags = "RTU实时生产数据")
@RestController
@RequestMapping("/rtudata")
public class RtuDataController {

    @Autowired
    private RtuDataService rtuDataService;

    @Autowired
    private RtuDataListener rtuDataListener;
    @Autowired
    private RtuDataMapper rtuDataMapper;
    @Autowired
    private UserService userService;
    @Autowired
    QjService qjService;

    @Autowired
    RtuDataService2 rtuDataService2;

    @Autowired
    FindLastMservice findLastMservice;

    @PostMapping("selectByMutiOptionsPage")
    @ApiOperation("按条件查询(多选)分页")
    @LogAnnotation(module = "RTU实时生产数据", operator = "按条件查询(多选)")
    public Result selectByMutiOptionsPage(String userName, @RequestBody RtuDataVo rtuDataVo, String date, int sort, int current, int size) {
        int department = userService.selectUserByuserName(userName).getUser_department_id();
        String ym = null;
        if (department == 2)
            ym = "川渝";
        if (department == 3)
            ym = "大庆";
        Page<RtuData> rtuDataPage = new Page<RtuData>(current, size);
        int len = rtuDataVo.getOptions().size();
        String down = "";
        String up = "";
//        日期查询
        if (StringUtils.isNotBlank(date)) {
            String[] dates = date.split(",");
            down = dates[0];
            up = dates[1];
        }
        List jhs = null;
        List<QjVo> qjvos = new LinkedList<>();
        List<String> zwbhs = null;
        List<String> ywbhs = null;
        if (len == 0) {
//            这个操作不清楚
//            return Result.success(null);
        } else if (rtuDataVo.getProperty().equals("jh")) {
            qjvos = qjService.findJhByJhs(rtuDataVo.getOptions());
        } else if (rtuDataVo.getProperty().equals("scq")) {
            qjvos = qjService.findbhByScq(rtuDataVo.getOptions());
//            jhs = qjService.selectJhByScq(rtuDataVo.getOptions());
        } else if (rtuDataVo.getProperty().equals("ym")) {
            qjvos = qjService.findbhByYm(rtuDataVo.getOptions());
//            jhs = qjService.selectJhByYm(rtuDataVo.getOptions());
        } else if (rtuDataVo.getProperty().equals("zm")) {
            qjvos = qjService.findbhByZm(rtuDataVo.getOptions());
//            jhs = qjService.selectJhByZm(rtuDataVo.getOptions());
        }
        if (len != 0) {
            zwbhs = new LinkedList<>();
            ywbhs = new LinkedList<>();
            for (QjVo qjvo : qjvos) {
                zwbhs.add(qjvo.getZwbh());
                ywbhs.add(qjvo.getYwbh());
            }
        }

        Page<RtuData> rtuDataPage1 = rtuDataMapper.selectByMutiOptionsByAllJh(rtuDataPage, up, down, sort, zwbhs, ywbhs, ym);
        return Result.success(rtuDataPage1)
                .setTotalData((int) rtuDataPage1.getTotal())
                .setTotalPage((int) rtuDataPage1.getPages());
    }



    @PostMapping("selectByOptions")
    @ApiOperation("按条件查询")
    @LogAnnotation(module = "RTU实时生产数据", operator = "按条件查询")
    public Result selectByOptions(String userName, @RequestBody RtuData rtuData) {
        int department = userService.selectUserByuserName(userName).getUser_department_id();
        return rtuDataService.selectByOptions(rtuData, department);
    }

    @PostMapping("selectByMutiOptions")
    @ApiOperation("按条件查询(多选)")
    @LogAnnotation(module = "RTU实时生产数据", operator = "按条件查询（多选）")
    public Result selectByMutiOptions(String userName, @RequestBody RtuDataVo rtuDataVo, String date, int sort) {
        int department = userService.selectUserByuserName(userName).getUser_department_id();
        return rtuDataService.selectByMutiOptions(rtuDataVo, date, sort, department);
    }



    @PostMapping("latestdata3")
    @ApiOperation("组态图读取所有井最新数据   已处理好的数据")
    @LogAnnotation(module = "RTU实时生产数据", operator = "读取所有井最新数据  已处理好的数据")
    @JHPermission
    public Result findLatestData3( @RequestParam(required = false) List<String> ywbhs, @RequestParam(required = false) List<String> zwbhs) {
//        return rtuDataService.findLatestData5(ywbhs,zwbhs);
        return rtuDataService.findLatestData(ywbhs,zwbhs);
    }





    @PostMapping("selectAll")
    @ApiOperation("查询全部数据")
    @LogAnnotation(module = "RTU实时生产数据", operator = "查询全部数据")
    public Result selectAll(String userName) {
        int department = userService.selectUserByuserName(userName).getUser_department_id();
        return rtuDataService.selectAll(department);
    }

    @PostMapping("selectData")
    @ApiOperation("查询某个时间范围的数据(油压，套压，井口温度)")
    @LogAnnotation(module = "RTU实时生产数据", operator = "查询某个时间范围数据(油压，套压，井口温度)")
    public Result selectData(String userName, String properties, String ywbh, String date) {
        return rtuDataService.selectData(ywbh, date, properties);
    }


    @PostMapping("addByExcel")
    @ApiOperation(value = "excel表导入到数据库")
    @LogAnnotation(module = "rtu实时数据", operator = "excel表导入到数据库")
    public Result insertByExcel(String userName, @RequestParam("excelFile") MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
        ExcelReaderBuilder read = EasyExcel.read(inputStream, RtuData.class, rtuDataListener);
        ExcelReaderSheetBuilder sheet = read.sheet();
        sheet.doRead();
        return Result.success(null);
    }

    @GetMapping("outExcel")
    @ApiOperation(value = "导出为excel")
    @LogAnnotation(module = "实时数据", operator = "导出为excel")
    public void outExcel(String userName, HttpServletResponse response, String end, String start, String[] jhs) throws IOException {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("实时生产数据", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + fileName + ".xlsx");
        ExcelWriterBuilder workbook = EasyExcel.write(response.getOutputStream(), RtuData.class);
        ExcelWriterSheetBuilder sheet = workbook.sheet();
        int department = userService.selectUserByuserName(userName).getUser_department_id();
        List<RtuData> list = rtuDataService.selectListByJHAndDate(department, jhs, start, end);
        sheet.doWrite(list);
    }



    @GetMapping("outExcelMultiThread")
    @ApiOperation(value = "导出为excel 多线程")
    @LogAnnotation(module = "实时数据", operator = "导出为excel 多线程")
    @JHPermission
    public void outExcelMultiThread(HttpServletResponse response, @RequestParam(required = false) String startDate,
                                    @RequestParam(required = false) String endDate, @RequestParam(required = false) List<String> ywbhs,
                                    @RequestParam(required = false) List<String> zwbhs) throws IOException {
        List<String> finalYwbhs = ywbhs;
        List<String> finalZwbhs = zwbhs;


        long start = System.currentTimeMillis();

        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("采气井日数据", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + fileName + ".xlsx");
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), Qba01.class).build();
        WriteSheet writeSheet = EasyExcel.writerSheet("sheet").build();

        LambdaQueryWrapper<RtuData> qba01LambdaQueryWrapper = new LambdaQueryWrapper<>();
        qba01LambdaQueryWrapper.orderByDesc(RtuData::getCjsj);
        qba01LambdaQueryWrapper.and(q -> {
            q.in(RtuData::getJh, finalYwbhs).or().in(RtuData::getJh, finalZwbhs);
        });

        if (StringUtils.isNotBlank(startDate))
            qba01LambdaQueryWrapper.ge(RtuData::getCjsj, DateUtils.stringTosqldate(startDate));
        if (StringUtils.isNotBlank(endDate))
            qba01LambdaQueryWrapper.ge(RtuData::getCjsj, DateUtils.stringTosqldate(endDate));


        int count = rtuDataService.count(qba01LambdaQueryWrapper);
        System.out.println(count);
        int size = 1000;
        int times = count / size;
        System.out.println(times);

//        times=10;

//      存储每个线程取出的数据
        LinkedList<Future<List>> records = new LinkedList<>();


        for (int i = 0; i <= times; i++) {
            Future<List> future = rtuDataService2.pageForMultiThreadForExcel(qba01LambdaQueryWrapper, i, size, records);
            records.add(future);
        }

        while (!records.isEmpty()) {
            Future<List> first = records.pop();
//          如果为空继续循环，直到不为空就开始写入excel
            while (!first.isDone()) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try {
                excelWriter.write(first.get(), writeSheet);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println(writeSheet);
        long end = System.currentTimeMillis();

        System.out.println((end - start) / 1000);

        excelWriter.finish();
        response.getOutputStream().flush();


    }
}
